package service

import (
	"errors"
	"go-gin-init/app/DB/mysql"
	"go-gin-init/app/models/model"
	"go.uber.org/zap"
	"gorm.io/gorm"
)

var user_service UserModel

type UserModel interface {
	FindByUserName(string) (*model.User, error)
	PageListUser(SearchTest string, PageNum int64, PageSize int64) ([]*model.User, error)
	CreateUser(m map[string]interface{}) error
	FindById(int64) (*model.User, error)
	UpdateUser(*model.User) error
	DeleteUser(id int64) error
}

type defaultUserModel struct {
	*gorm.DB
}

func NewDefaultUserModel() UserModel {
	once.Do(func() {
		user_service = &defaultUserModel{mysql.GetGormDB()}
	})
	return user_service
}

func (m *defaultUserModel) PageListUser(SearchTest string, PageNum int64, PageSize int64) ([]*model.User, error) {

	var users []model.User
	offset := (PageNum - 1) * PageSize
	result := m.Where(" tags LIKE ? and isDelete = 0", "%"+SearchTest+"%").Offset(int(offset)).Limit(int(PageSize)).Find(&users)
	if result.Error != nil {
		zap.L().Error("sql-USER: PageListUser err", zap.Error(result.Error))
		return nil, result.Error
	}
	var _model []*model.User
	for i := 0; i < len(users); i++ {
		_model = append(_model, &users[i])
	}
	return _model, nil

}

func (m *defaultUserModel) FindById(id int64) (*model.User, error) {

	user := model.User{}
	tx := m.Where("id = ? and isDelete = 0", id).Take(&user)
	switch tx.Error {
	case nil:
		return &user, nil
	case gorm.ErrRecordNotFound:
		zap.L().Warn("sql-USER: FindById err", zap.Error(errors.New("NOT FOUND")))
		return nil, nil
	default:
		zap.L().Error("sql-USER: FindById", zap.Error(tx.Error))
		return nil, tx.Error
	}

}

func (m *defaultUserModel) FindByUserName(username string) (*model.User, error) {

	user := model.User{}
	// 数据库查询
	tx := m.Where("username = ? and isDelete = 0", username).Take(&user)
	switch tx.Error {
	case nil:
		return &user, nil
	case gorm.ErrRecordNotFound:
		zap.L().Warn("sql-USER: FindByUserName err", zap.Error(errors.New("NOT FOUND")))
		return nil, nil
	default:
		zap.L().Error("sql-USER: FindByUserName", zap.Error(tx.Error))
		return nil, tx.Error
	}

}

func (m *defaultUserModel) CreateUser(userMap map[string]interface{}) error {

	tx := m.Model(&model.User{}).Create(userMap)

	err := tx.Error
	if err != nil {
		zap.L().Error("sql-USER: CreateUser err", zap.Error(err))
		return err
	}

	return nil
}

func (m *defaultUserModel) UpdateUser(newUser *model.User) error {

	_, err := m.FindById(newUser.Id)
	if err != nil {
		return err
	}

	tx := m.Model(newUser).Where("id = ? and isDelete = 0", newUser.Id).Updates(newUser)
	if tx.Error != nil {
		zap.L().Error("sql-USER: UpdateUser err", zap.Error(err))
		return err
	}

	if tx.RowsAffected == 0 {
		zap.L().Warn("sql-USER: UpdateUser err:修改行数为空")
	}

	return nil
}

func (m *defaultUserModel) DeleteUser(id int64) error {

	_, err := m.FindById(id)
	if err != nil {
		zap.L().Error("sql-USER: DeleteUser》》》》FindById err", zap.Error(err))
		return err
	}

	tx := m.Model(&model.User{}).Where("id = ? and isDelete = 0", id).Update("isDelete", 1)
	err = tx.Error

	if err != nil {
		zap.L().Error("sql-USER: DeleteUser err", zap.Error(err))
		return err
	}
	if tx.RowsAffected == 0 {
		zap.L().Warn("sql-USER: DeleteUser err:修改行数为空")
	}

	return nil
}
